﻿using App22_Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace App22 {
  public partial class Form1 : Form {
    private ICalC calculator = null;

    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {
      // Serach plugin
      refreshPlugins();
      // Bind to cbb

    }

    private void refreshPlugins() {
      IEnumerable<ICalC> calculators = ScanCalculator();
      updateUI(calculators);
    }

    private void updateUI(IEnumerable<ICalC> calculators) {
      comboBox1.Items.Clear();
      foreach (var calc in calculators) {
        comboBox1.Items.Add(calc);
      }
      if (comboBox1.Items.Count > 0) {
        comboBox1.SelectedIndex = 0;
      }
      
    }

    private IEnumerable<ICalC> ScanCalculator() {
      var dir = new DirectoryInfo(Application.StartupPath); // current path
      var files = dir.EnumerateFiles("*.dll").Concat(dir.EnumerateFiles("*.exe"));
      // EnumerateFiles - yield return;
      foreach (var file in files) {
        Assembly asm = Assembly.LoadFile(file.FullName);
        var q = from t in asm.GetTypes()
                where t.IsClass //&& t.IsAssignableFrom(typeof(ICalC))
                && (typeof(ICalC)).IsAssignableFrom(t)
                select t;
        foreach (var type in q) {          
          // new instance from dll
          var calc = Activator.CreateInstance(type);
          yield return (ICalC)calc;
        }
      }
    }

    private void updateResult() {
      if (calculator == null) {
        label1.Text = "N/A";
      }
      else {
        label1.Text = calculator.Execute(
          (int)numericUpDown1.Value, 
          (int)numericUpDown2.Value).ToString();
      }
    }

    #region Event Handlers

    private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
      updateResult();
    }

    private void numericUpDown2_ValueChanged(object sender, EventArgs e) {
      updateResult();
    }

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
      if (comboBox1.SelectedItem != null) {
        this.calculator = (ICalC)comboBox1.SelectedItem;
      }
      updateResult();
    }

    #endregion
  }
}
